package org.shunya.duplicatefileperquisitor.gui;

import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;

import static java.nio.file.Files.newDirectoryStream;
import static java.nio.file.Files.newInputStream;

public class FilePathTreeItem extends CheckBoxTreeItem<String> {
    public static Image folderCollapseImage;
    public static Image folderExpandImage;
    public static Image fileImage;
    //this stores the full path to the file or directory
    private String fullPath;
    private boolean isDirectory;
    private Path path;

    static {
        try {
            folderCollapseImage = new Image(newInputStream(FileSystems.getDefault().getPath("./src/main/resources/images/folder.png")), 20.0, 20.0, true, true);
            folderExpandImage = new Image(newInputStream(FileSystems.getDefault().getPath("./src/main/resources/images/folder_open.png")), 20.0, 20.0, true, true);
            fileImage = new Image(newInputStream(FileSystems.getDefault().getPath("./src/main/resources/images/text-x-generic.png")), 20.0, 20.0, true, true);
        } catch (IOException e) {

        }
    }

    public FilePathTreeItem(Path file) {
        super(file.toString());
        this.path = file;
        this.fullPath = file.toString();
//test if this is a directory and set the icon
        if (Files.isDirectory(file)) {
            this.isDirectory = true;
            this.setGraphic(new ImageView(folderCollapseImage));
        } else {
            this.isDirectory = false;
            this.setGraphic(new ImageView(fileImage));
            //if you want different icons for different file types this is where you'd do it
        }

//set the value
        if (!fullPath.endsWith(File.separator)) {
            //set the value (which is what is displayed in the tree)
            String value = file.toString();
            int indexOf = value.lastIndexOf(File.separator);
            if (indexOf > 0) {
                this.setValue(value.substring(indexOf + 1));
            } else {
                this.setValue(value);
            }
        }
    }

    void handleBranchCollapsedEvent(FilePathTreeItem source) {

        if (source.isDirectory() && source.isExpanded()) {
            ImageView iv = (ImageView) source.getGraphic();
            iv.setImage(folderExpandImage);
        }
    }

    void handleBranchExpandedEvent(FilePathTreeItem source) {

        if (source.isDirectory() && !source.isExpanded()) {
            ImageView iv = (ImageView) source.getGraphic();
            iv.setImage(folderCollapseImage);
        }
        try {
            if (source.getChildren().isEmpty()) {
                Path path = Paths.get(source.getFullPath());
                if (Files.isDirectory(path)) {
                    DirectoryStream<Path> dir = newDirectoryStream(path);
                    for (Path file : dir) {
                        if (Files.isHidden(file) || !Files.isDirectory(file))
                            continue;
                        FilePathTreeItem treeNode = new FilePathTreeItem(file);
                        source.getChildren().add(treeNode);
                    }
                }
            } else {
                //if you want to implement rescanning a directory for changes this would be the place to do it
            }
        } catch (IOException x) {
            x.printStackTrace();
        }
    }

    public Path getPath() {
        return path;
    }

    public String getFullPath() {
        return (this.fullPath);
    }

    public boolean isDirectory() {
        return (this.isDirectory);
    }
}